import java.util.PriorityQueue;
import java.util.concurrent.Executors;
class MytimerTask implements Comparable<MytimerTask>{
    private Runnable task;
    private long time;
    public MytimerTask(Runnable task,long time){
        this.time=time;
        this.task=task;
    }
    public void run(){
        task.run();
    }
    public long gettime(){
        return time;
    }

    @Override
    public int compareTo(MytimerTask o) {
        return (int)(this.time-o.time);
    }
}
class Mytimer{
    Object locker=new Object();
    PriorityQueue<MytimerTask> priorityQueue=new PriorityQueue<>();
    public void schedule(Runnable task,long delay){
        synchronized(locker){
            MytimerTask myTimerTask1=new MytimerTask(task,System.currentTimeMillis()+delay);
            priorityQueue.offer(myTimerTask1);
            locker.notifyAll();
        }
    }
    public Mytimer(){
        Thread t=new Thread(()->{
            while(true){
                synchronized(locker){
                    while(priorityQueue.isEmpty()){
                        try {
                            locker.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    MytimerTask task=priorityQueue.peek();
                    if(task.gettime()>System.currentTimeMillis()){
                        try {
                            locker.wait(task.gettime()-System.currentTimeMillis());
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }else{
                        task.run();
                        priorityQueue.poll();
                    }
                }
            }
        });
        t.start();
        }
    }
public class demo44 {
    public static void main(String[] args) {
        Mytimer mytimer=new Mytimer();
        mytimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 3000");
            }
        },3000);
        mytimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 2000");
            }
        },2000);
        mytimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 1000");
            }
        },1000);
        //Executors.newScheduledThreadPool(4);
    }
}
